#include <QColor>
#include <QMessageBox>
#include "Networking/usermanager.h"
#include "MainWindow/mainwindow.h"
#include "Preferences/preferences.h"

UserManager::UserManager(Session *newParent = 0)
{
	session = newParent;

	localUserId = 0;

	userList.push_back(User());

	connect(Preferences::getInstance(), SIGNAL(changed()), this, SLOT(preferencesChanged()));
}

User UserManager::getLocalUser()
{
		return userList.at(localUserId);
}

/**
  *	Change the local user details, and send changes to the sever
  */
void UserManager::setLocalUser(User usr)
{
        localUserId = usr.getId();
	userList.replace(localUserId, usr);

	if (session->isConnectedToServer())
	{
		session->sendMessage(UserMessage(usr).toBytes());
	}

	//update GUI for local changes
	MainWindow::getInstance()->updateUserList(usr.getId(), usr.getName(), usr.getColour(), usr.getOnlineStatus());
}

void UserManager::deleteUser(int id)
{
	userList[id].setOnlineStatus(false);
}

/**
  *	Given a UserMessage, will add the new data to the list in the appropriate place
  */
void UserManager::processUserMessage(UserMessage newUser)
{
	User usr = newUser.getUser();

	if (usr.getId() < userList.size())
	{
		userList.replace(usr.getId(), usr);

		session->getDocumentManager()->rehighlightAll();	//rehighlight all of the documents
	}
	else
	{
		userList.insert(usr.getId(), usr);
	}

	qDebug("Client has recieved user info for (%d, %s)", usr.getId(), usr.getName().toAscii().data());

	MainWindow::getInstance()->updateUserList(usr.getId(), usr.getName(), usr.getColour(), usr.getOnlineStatus());
}

/**
  * Processes a list of users when connecting to a server and sends out local info
  */
void UserManager::userServerHandshake(QList<UserMessage> newUsers)
{
	User localUser = userList.at(localUserId);
	localUserId = newUsers.size();
	localUser.setId(localUserId);

	foreach(UserMessage usr, newUsers)
	{
		processUserMessage(usr);
	}	

	userList.insert(localUserId, localUser);
	session->sendMessage(UserMessage(localUser).toBytes());
}

void UserManager::preferencesChanged()
{
	QString newName = Preferences::getInstance()->getValue(Preferences::SETTING_DEFAULT_NAME).toString();
	QColor newColour = Preferences::getInstance()->getValue(Preferences::SETTING_DEFAULT_TEXT_COLOUR).value<QColor>();

	User localUser = userList.at(localUserId);

	//if no changes have been made
	if (localUser.getName() == newName && localUser.getColour() == newColour)
		return;

	if (localUser.getName() != newName)
		localUser.setName(newName);

	if (localUser.getColour() != newColour)
		localUser.setColour(newColour);

	setLocalUser(localUser);	//apply and send out changes
}

void UserManager::saveSession(QString filename)
{
    //Save out information for each user
    QFile file(filename+"_userL.wed");
    file.open(QIODevice::WriteOnly);

    QTextStream out(&file);

    QList<User>::iterator i;
    i=userList.begin();

    out << QString::number(userList.size()) << "\n";    //Current number of users. Online and offline

    while(i!=userList.end())
    {
        out << i->getAll() << "\n";
        i++;
    }

    file.close();

}

void UserManager::loadSession(QString filename)
{
    bool found = false;     //Used to confirm if a user is returning

    //Open file and load up previous users
    QFile file(filename+"_userL.wed");
    if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QMessageBox msgBox;
        msgBox.setText("Error: Unable to open " + filename);
        msgBox.exec();
        return;     //Could not open up user list file
    }

    QTextStream in(&file);

    int noUsers = QString(in.readLine()).toInt();

    QString userLine = "";
    userLine = in.readLine();

    User* current = new User(userList.first());     //Preserve current user on the list
    userList.pop_back();    //Take off actual list

    for(int x=0; x< noUsers; x++)      //More users in the file
    {
        //Break line into pieces
        QStringList lineData = userLine.split(":");

        //Create QColor
        QColor color = this->decodeColor(lineData.at(2).toLocal8Bit().constData());

        //Create user
        User newUser(QString(lineData.at(0).toLocal8Bit().constData()).toInt(), lineData.at(1).toLocal8Bit().constData(), color, "", -1, false);

        //Check if names match
        QMessageBox msgBox;
        int ret = -1;

	if(current->getName()==newUser.getName())
        {
            msgBox.setText("Is this the same " + newUser.getName() + " that was previously editing this document?");
            msgBox.setInformativeText("Click 'yes' to resume as this user?");
            msgBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
            msgBox.setDefaultButton(QMessageBox::Yes);
            ret = msgBox.exec();
        }

        if(ret == QMessageBox::Yes)
        {
            newUser.setOnlineStatus(true);
            UserMessage newU(newUser);
            this->processUserMessage(newU);
            this->setLocalUser(newUser);
            found = true;
            ret = -1;
        }else{
            UserMessage newU(newUser);
            this->processUserMessage(newU);
        }

        //Read in next user/line
        userLine = in.readLine();       //Read in next line of input

    }

    //If no user was matched, add the current user back onto the list
    if(!found)
    {
        current->setId(userList.size());
        UserMessage newU(*current);
        this->processUserMessage(newU);
        this->setLocalUser(*current);
    }

    delete current;
}

QColor UserManager::decodeColor(QString col)
{
    QStringList colorData = col.split("*");

    QColor myColor(QString(colorData.at(0).toLocal8Bit().constData()).toInt(),
                   QString(colorData.at(1).toLocal8Bit().constData()).toInt(),
                   QString(colorData.at(2).toLocal8Bit().constData()).toInt(),
                   QString(colorData.at(3).toLocal8Bit().constData()).toInt());

    return myColor;
}
